#ifndef FILE_MERGER_HPP_
#define FILE_MERGER_HPP_

class FileMerger{
	private:
		std::vector<File*> merge_file_list;
		File* output_file;
		//while merging via temporary files, must unlink in order to
		//have secure delete, no cleanup for ordinary files
		void _clean_up_file(char* path) {	   		
	   		unlink(path);
	   	}
	   	void _remove(int i) {
	   		_clean_up_file(merge_file_list[i] -> get_path());
	   		merge_file_list.erase(merge_file_list.begin() + i);
	   	}
	   	void _get_slice(std::vector<int>& slice, std::vector<bool>& read_perm) {
	   			int size = merge_file_list.size();
				for (int i = 0; i < size; ++i) {
					if (read_perm[i]) {
						int status;
						slice[i] = File::read_stream_integer(*merge_file_list[i], &status);
						read_perm[i] = false;
						if (status == EOF) {
							slice.erase(slice.begin() + i);							
							_remove(i);
						}

					}
				}	   		
	   	}
	   	int _find_min(std::vector<int>& slice) {
	   		int size = slice.size();
	   		if (size == 0)
	   			return -1;
	   		int min = 0;
	   		for (int i = 0; i < size; ++i) {
	   			if (slice[i] < slice[min]) {
	   				min = i;
	   			}
	   		}
	   		return min;
	   	}
	public:
	   FileMerger(std::vector<File*>& part, File* output) {
	   		merge_file_list = part;
	   		output_file = output;
	   }
	   //method merges /tmp files(watch constructor), takes one by one integer
	   //and puts it to output stream - optimization bug, watch case when all
	   //values in tmp1 less than in tmp2
	   void merge() {
	   	  std::vector<int> slice(merge_file_list.size());
	   	  std::vector<bool> read_perm(merge_file_list.size(), true); //all must read first
	   	  _get_slice(slice, read_perm);
	   	  while (!merge_file_list.empty()) {
	   	  	  int position = _find_min(slice);
	   	  	  if (position >= 0) {
		   	  	  File::write_stream_integer(*output_file, slice[position]);
		   	  	  read_perm[position] = true;
		   	  }
		   	  _get_slice(slice, read_perm); 
	   	  }
	   }
};
#endif